package net.entelijan.cobean.examples.showcase.table;

import static org.junit.Assert.assertEquals;

import java.util.ArrayList;
import java.util.List;

import net.entelijan.cobean.core.ColumnDesc;
import net.entelijan.cobean.core.IMultiSelectionListCobean;
import net.entelijan.cobean.core.SelectionMode;
import net.entelijan.cobean.core.TextComponentActionMode;
import net.entelijan.cobean.examples.showcase.CobeanExamplesTestUtil;
import net.entelijan.cobean.examples.showcase.ShowcaseTestFrame;
import net.entelijan.cobean.examples.util.Locale;
import net.entelijan.cobean.examples.util.ExamplesUtil;
import net.entelijan.cobean.table.DefaultTableInitializer;

import org.fest.swing.data.TableCell;
import org.fest.swing.fixture.FrameFixture;
import org.fest.swing.fixture.JButtonFixture;
import org.fest.swing.fixture.JTableFixture;
import org.fest.swing.fixture.JTextComponentFixture;
import org.junit.Test;

@SuppressWarnings("unused")
public class FilterActionTableFestTestCase {

	@Test
	public void test() {
		FilterActionTablePanel panel = new FilterActionTablePanel();
		ShowcaseTestFrame frame = new ShowcaseTestFrame(panel);
		FrameFixture showcaseFix = new FrameFixture(frame);
		try {
			showcaseFix.show();

			DefaultTableInitializer<Locale> initializer = new DefaultTableInitializer<Locale>();
			initializer.setCoTable(panel.getTable());
			initializer.setCoFilterInput(panel.getFilterTextField());
			initializer.setCoFilterButton(panel.getFilterButton());
			initializer.setFilterActionMode(TextComponentActionMode.ON_ACTION);
			initializer.setSelectionMode(SelectionMode.MULTIPLE_INTERVAL);
			List<ColumnDesc> colDescs = createColumnDescriptions();
			initializer.setColumnDescs(colDescs);
			final IMultiSelectionListCobean<Locale> cobean = initializer
					.initialize();
			final List<Locale> data = ExamplesUtil.createLocales();
			cobean.setValue(data);

			JTableFixture table = showcaseFix
					.table("FilterActionTablePanel.table");
			JTextComponentFixture filterTextBox = showcaseFix
					.textBox("FilterActionTablePanel.filterTextField");
			JButtonFixture button = showcaseFix
					.button("FilterActionTablePanel.filterButton");
			// Test initial data
			{
				table.requireContents(getLocalesUnsortedUnfiltered());
				pauseShort();
				table.selectCell(TableCell.row(2).column(0));
				pauseShort();
				List<Locale> sel = cobean.getSelectedValue();
				Locale selBean = sel.get(0);
				CobeanExamplesTestUtil.assertObjectValue(data.get(2), selBean,
						colDescs, 0);
			}
			// Test filtering
			{
				filterTextBox.enterText("Eng");
				button.click();
				pauseShort();
				table.selectCell(TableCell.row(2).column(0));
				pauseShort();
				List<Locale> sel = cobean.getSelectedValue();
				CobeanExamplesTestUtil.assertObjectValue(data.get(23), sel
						.get(0), colDescs, 0);
			}
			// Test multiselection
			{
				TableCell c1 = TableCell.row(2).column(0);
				TableCell c2 = TableCell.row(3).column(0);
				TableCell c3 = TableCell.row(5).column(0);
				table.selectCells(c1, c2, c3);
				pauseShort();
				List<Locale> sel = cobean.getSelectedValue();
				assertEquals(3, sel.size());
				CobeanExamplesTestUtil.assertObjectValue(data.get(23), sel
						.get(0), colDescs, 2);
				CobeanExamplesTestUtil.assertObjectValue(data.get(25), sel
						.get(1), colDescs, 3);
				CobeanExamplesTestUtil.assertObjectValue(data.get(62), sel
						.get(2), colDescs, 5);
			}
		} finally {
			pauseShort();
			showcaseFix.cleanUp();
		}
	}

	private List<ColumnDesc> createColumnDescriptions() {
		List<ColumnDesc> colDescs = new ArrayList<ColumnDesc>();
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("displayLanguage");
			colDesc.setHeaderName("Language(filterable)");
			colDesc.setFilterable(true);
			colDescs.add(colDesc);
		}
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("language");
			colDesc.setHeaderName("Language");
			colDescs.add(colDesc);
		}
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("ISO3Language");
			colDesc.setHeaderName("Language ISO3");
			colDesc.setWidth(10);
			colDescs.add(colDesc);
		}
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("displayCountry");
			colDesc.setHeaderName("Country(sortable)");
			colDesc.setSortable(true);
			colDescs.add(colDesc);
		}
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("country");
			colDesc.setHeaderName("Country(sortable)");
			colDesc.setSortable(true);
			colDescs.add(colDesc);
		}
		{
			ColumnDesc colDesc = new ColumnDesc();
			colDesc.setPropertyName("ISO3Country");
			colDesc.setHeaderName("Country ISO3(sortable)");
			colDesc.setSortable(true);
			colDescs.add(colDesc);
		}
		return colDescs;
	}

	private String[][] getLocalesUnsortedUnfiltered() {
		return new String[][] {
				{ "Japanese", "ja", "jpn", "Japan", "JP", "jpn" },
				{ "Spanish", "es", "spa", "Peru", "PE", "spa" },
				{ "Japanese", "ja", "jpn", "Japan", "JP", "jpn" },
				{ "Spanish", "es", "spa", "Panama", "PA", "spa" },
				{ "Serbian", "sr", "srp", "Bosnia and Herzegovina", "BA", "srp" },
				{ "Spanish", "es", "spa", "Guatemala", "GT", "spa" },
				{ "Arabic", "ar", "ara", "United Arab Emirates", "AE", "ara" },
				{ "Norwegian", "no", "nor", "Norway", "NO", "nor" },
				{ "Albanian", "sq", "sqi", "Albania", "AL", "sqi" },
				{ "Arabic", "ar", "ara", "Iraq", "IQ", "ara" },
				{ "Arabic", "ar", "ara", "Yemen", "YE", "ara" },
				{ "Portuguese", "pt", "por", "Portugal", "PT", "por" },
				{ "Greek", "el", "ell", "Cyprus", "CY", "ell" },
				{ "Arabic", "ar", "ara", "Qatar", "QA", "ara" },
				{ "Macedonian", "mk", "mkd", "Macedonia", "MK", "mkd" },
				{ "German", "de", "deu", "Switzerland", "CH", "deu" },
				{ "English", "en", "eng", "United States", "US", "eng" },
				{ "Finnish", "fi", "fin", "Finland", "FI", "fin" },
				{ "English", "en", "eng", "Malta", "MT", "eng" },
				{ "Slovenian", "sl", "slv", "Slovenia", "SI", "slv" },
				{ "Slovak", "sk", "slk", "Slovakia", "SK", "slk" },
				{ "Turkish", "tr", "tur", "Turkey", "TR", "tur" },
				{ "Arabic", "ar", "ara", "Saudi Arabia", "SA", "ara" },
				{ "English", "en", "eng", "United Kingdom", "GB", "eng" },
				{ "Serbian", "sr", "srp", "Serbia and Montenegro", "CS", "srp" },
				{ "English", "en", "eng", "New Zealand", "NZ", "eng" },
				{ "Norwegian", "no", "nor", "Norway", "NO", "nor" },
				{ "Lithuanian", "lt", "lit", "Lithuania", "LT", "lit" },
				{ "Spanish", "es", "spa", "Nicaragua", "NI", "spa" },
				{ "Irish", "ga", "gle", "Ireland", "IE", "gle" },
				{ "French", "fr", "fra", "Belgium", "BE", "fra" },
				{ "Spanish", "es", "spa", "Spain", "ES", "spa" },
				{ "Arabic", "ar", "ara", "Lebanon", "LB", "ara" },
				{ "French", "fr", "fra", "Canada", "CA", "fra" },
				{ "Estonian", "et", "est", "Estonia", "EE", "est" },
				{ "Arabic", "ar", "ara", "Kuwait", "KW", "ara" },
				{ "Serbian", "sr", "srp", "Serbia", "RS", "srp" },
				{ "Spanish", "es", "spa", "United States", "US", "spa" },
				{ "Spanish", "es", "spa", "Mexico", "MX", "spa" },
				{ "Arabic", "ar", "ara", "Sudan", "SD", "ara" },
				{ "Indonesian", "in", "ind", "Indonesia", "ID", "ind" },
				{ "Spanish", "es", "spa", "Uruguay", "UY", "spa" },
				{ "Latvian", "lv", "lav", "Latvia", "LV", "lav" },
				{ "Portuguese", "pt", "por", "Brazil", "BR", "por" },
				{ "Arabic", "ar", "ara", "Syria", "SY", "ara" },
				{ "Spanish", "es", "spa", "Dominican Republic", "DO", "spa" },
				{ "French", "fr", "fra", "Switzerland", "CH", "fra" },
				{ "Hindi", "hi", "hin", "India", "IN", "hin" },
				{ "Spanish", "es", "spa", "Venezuela", "VE", "spa" },
				{ "Arabic", "ar", "ara", "Bahrain", "BH", "ara" },
				{ "English", "en", "eng", "Philippines", "PH", "eng" },
				{ "Arabic", "ar", "ara", "Tunisia", "TN", "ara" },
				{ "German", "de", "deu", "Austria", "AT", "deu" },
				{ "Dutch", "nl", "nld", "Netherlands", "NL", "nld" },
				{ "Spanish", "es", "spa", "Ecuador", "EC", "spa" },
				{ "Chinese", "zh", "zho", "Taiwan", "TW", "zho" },
				{ "Arabic", "ar", "ara", "Jordan", "JO", "ara" },
				{ "Icelandic", "is", "isl", "Iceland", "IS", "isl" },
				{ "Spanish", "es", "spa", "Colombia", "CO", "spa" },
				{ "Spanish", "es", "spa", "Costa Rica", "CR", "spa" },
				{ "Spanish", "es", "spa", "Chile", "CL", "spa" },
				{ "Arabic", "ar", "ara", "Egypt", "EG", "ara" },
				{ "English", "en", "eng", "South Africa", "ZA", "eng" },
				{ "Thai", "th", "tha", "Thailand", "TH", "tha" },
				{ "Greek", "el", "ell", "Greece", "GR", "ell" },
				{ "Italian", "it", "ita", "Italy", "IT", "ita" },
				{ "Hungarian", "hu", "hun", "Hungary", "HU", "hun" },
				{ "English", "en", "eng", "Ireland", "IE", "eng" },
				{ "Ukrainian", "uk", "ukr", "Ukraine", "UA", "ukr" },
				{ "Polish", "pl", "pol", "Poland", "PL", "pol" },
				{ "French", "fr", "fra", "Luxembourg", "LU", "fra" },
				{ "Dutch", "nl", "nld", "Belgium", "BE", "nld" },
				{ "English", "en", "eng", "India", "IN", "eng" },
				{ "Catalan", "ca", "cat", "Spain", "ES", "cat" },
				{ "Arabic", "ar", "ara", "Morocco", "MA", "ara" },
				{ "Spanish", "es", "spa", "Bolivia", "BO", "spa" },
				{ "English", "en", "eng", "Australia", "AU", "eng" },
				{ "Chinese", "zh", "zho", "Singapore", "SG", "zho" },
				{ "Spanish", "es", "spa", "El Salvador", "SV", "spa" },
				{ "Russian", "ru", "rus", "Russia", "RU", "rus" },
				{ "Korean", "ko", "kor", "South Korea", "KR", "kor" },
				{ "Arabic", "ar", "ara", "Algeria", "DZ", "ara" },
				{ "Vietnamese", "vi", "vie", "Vietnam", "VN", "vie" },
				{ "Serbian", "sr", "srp", "Montenegro", "ME", "srp" },
				{ "Arabic", "ar", "ara", "Libya", "LY", "ara" },
				{ "Chinese", "zh", "zho", "China", "CN", "zho" },
				{ "Belarusian", "be", "bel", "Belarus", "BY", "bel" },
				{ "Chinese", "zh", "zho", "Hong Kong", "HK", "zho" },
				{ "Hebrew", "iw", "heb", "Israel", "IL", "heb" },
				{ "Bulgarian", "bg", "bul", "Bulgaria", "BG", "bul" },
				{ "Maltese", "mt", "mlt", "Malta", "MT", "mlt" },
				{ "Spanish", "es", "spa", "Paraguay", "PY", "spa" },
				{ "French", "fr", "fra", "France", "FR", "fra" },
				{ "Czech", "cs", "ces", "Czech Republic", "CZ", "ces" },
				{ "Italian", "it", "ita", "Switzerland", "CH", "ita" },
				{ "Romanian", "ro", "ron", "Romania", "RO", "ron" },
				{ "Spanish", "es", "spa", "Puerto Rico", "PR", "spa" },
				{ "English", "en", "eng", "Canada", "CA", "eng" },
				{ "German", "de", "deu", "Germany", "DE", "deu" },
				{ "German", "de", "deu", "Luxembourg", "LU", "deu" },
				{ "Spanish", "es", "spa", "Argentina", "AR", "spa" },
				{ "Malay", "ms", "msa", "Malaysia", "MY", "msa" },
				{ "Croatian", "hr", "hrv", "Croatia", "HR", "hrv" },
				{ "English", "en", "eng", "Singapore", "SG", "eng" },
				{ "Arabic", "ar", "ara", "Oman", "OM", "ara" },
				{ "Thai", "th", "tha", "Thailand", "TH", "tha" },
				{ "Swedish", "sv", "swe", "Sweden", "SE", "swe" },
				{ "Danish", "da", "dan", "Denmark", "DK", "dan" },
				{ "Spanish", "es", "spa", "Honduras", "HN", "spa" }

		};
	}

	private synchronized void pauseShort() {
		try {
			wait(200);
		} catch (InterruptedException ex) {
			// Dont worry about that exception
		}
	}

	private synchronized void pauseMedium() {
		try {
			wait(1000);
		} catch (InterruptedException ex) {
			// Dont worry about that exception
		}
	}

	private synchronized void pauseLong() {
		try {
			wait(4000);
		} catch (InterruptedException ex) {
			// Dont worry about that exception
		}
	}

}
